home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
- # The above Perl path may vary on your system; fix it!!! -*- perl -*-
-
- # beh - Backend Error Handler
-
- # A wrapper for CUPS backends to make error handling configurable
-
- # Usually, if a CUPS backend exits with an error status other than zero
- # (for example if a printer is not turned on or not reachable on the
- # network), CUPS disables the print queue and one can only print again
- # if a system administrator re-enables the queue manually. Even restarting
- # CUPS (or rebooting) does not re-enable disabled queues.
- #
- # For system administrators this can get annoying, for newbie users
- # who are not aware of this problem it looks like that CUPS is severely
- # broken. They remove and re-install print queues, getting on the nerves
- # of distro install support, people, or even switch back to a proprietary
- # operating system.
- #
- # This script makes the handling of such backend errors configurable, so
- # that the problem can easily be worked around. The new possibilities are:
- #
- # - Let queues simply not being disabled. Simple approach, but job gets
- # lost.
- #
- # - Repeat a given number of times.
- #
- # - Repeat infinitely often, until the job gets finally through. This
- # is the standard of LPRng, and it eliminates loss of the job.
- #
- # - The interval between two attemts to run the backend can also be
- # configured.
- #
- # - Configuration is done independently for each print queue. So local
- # printers and network printers can be treated differently.
-
- # Save this file in your CUPS backend directory, usually
- # /usr/lib/cups/backend/ or /usr/local/lib/cups/backend/
- #
- # Mark this filter world-readable and world-executable. Restart CUPS to
- # make the new backend known to the spooler.
- #
- # See http://www.openprinting.org/cups-doc.html and the additional
- # instructions below.
-
- # beh - Backend Error Handler
- #
- # Copyright 2005 Till Kamppeter <till.kamppeter@gmail.com>
- #
- # This program is free software; you can redistribute it and/or modify it
- # under the terms of the GNU General Public License as published by the
- # Free Software Foundation; either version 2 of the License, or (at your
- # option) any later version.
- #
- # This program is distributed in the hope that it will be useful, but
- # WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
- # Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- # USA.
-
- # Usage:
- #
- # cp beh /usr/lib/cups/backend/
- # chmod 755 /usr/lib/cups/backend/beh
- # killall -HUP cupsd (or "/etc/init.d/cups restart")
- # lpadmin -p <queue name> -E -v beh:/<dd>/<att>/<delay>/<originaluri>
- #
- # with
- # <queue name>: The name of your print queue
- # <dd>: Don't Disable, if "1", beh always exits with zero
- # status, so the queue gets never disabled when the
- # original backend exits with an error. "0" carries
- # the error status of the last call of the backend
- # (after <att> retries) on to CUPS, so the queue
- # usually gets disabled.
- # <att>: Attempts, number of attempts to recall the backend
- # in case of an error. "0" means infinite retries. In
- # this case <dd> gets meaningless.
- # <delay>: Delay between two attempts to call the beckend, to
- # be given in seconds and as an integer number.
- # Meaningless if <att> is one.
- # <originaluri>: The original URI, which your queue had before.
- #
- # All parameters, especially, <dd>, <att>, and <delay> have always to
- # be specified, even if one of them is meaningless due to the setting of
- # the others.
- #
- # beh works with every backend except the "hp" backend of HPLIP.
- #
- # Example URIs:
- #
- # beh:/1/3/5/socket://printer:9100
- #
- # On the network printer with host name "printer" it is tried to access
- # 3 times with 5 second delays between the attempts. If the job still
- # fails, the queue is not disabled (and the job discarded).
- #
- # beh:/0/10/60/socket://printer:9100
- #
- # Retry 10 times in one minute intervals, disable the queue when still
- # not succeeding.
- #
- # beh:/1/0/60/usb://Brother/HL-5040%20series
- #
- # On a Brother HL-5040 on the USB try infinitely often until the printer
- # comes back, in intervals of one minute. This way the job does not get
- # lost when the printer is turned off and one can intendedly delay
- # printing by simply switching off the printer. The ideal configuration
- # for desktop printers and/or home users.
-
- # Acknowledgement
- #
- # Thanks to Jeff Hardy (hardyjm at potsdam dot edu) for writing the
- # "accsnmp" wrapper backend (http://fritz.potsdam.edu/projects/cupsapps/).
- # This backend showed me the trick how to write a universal wrapper
- # backend in a scripting language.
-
- use strict;
-
- $0 =~ m!^(.*)/([^/]+)\s*$!;
- my $progname = ($2 || $0);
- my $progpath = ($1 || "/usr/lib/cups/backend");
-
- if (!$ARGV[0]){
- print "network $progname \"Unknown\" \"Backend Error Handler\"\n";
- exit 0;
- }
-
- if (scalar(@ARGV) < 5 || scalar(@ARGV) > 6){
- print STDERR "ERROR: Usage: $progname job-id user title copies options [file]\n";
- exit 1;
- }
-
- my ($jobID, $userName, $jobTitle, $copies, $printOptions, $printFile) =
- @ARGV;
-
- my $tempFile;
- if (!$printFile) {
-
- my $jid = $jobID;
- my $uid = $userName;
- $jid =~ s/\W//g; #sanity check
- $uid =~ s/\W//g; #sanity check
- my $tmpDir = $ENV{TMPDIR};
- $tmpDir ||= "/tmp";
- $tempFile = "$tmpDir/$jid-$uid-cupsjob$$";
-
- open (OUT, ">$tempFile") or die "ERROR: Cannot write $tempFile: $!\n";
-
- while(<STDIN>){
- print OUT "$_";
- }
-
- close OUT;
-
- $printFile = $tempFile;
-
- # Backends should only produce multiple copies if a file name is
- # supplied (see CUPS Software Programmers Manual)
- $copies = 1;
-
- }
-
- my $uri = $ENV{DEVICE_URI};
- $uri =~ m!^$progname:/(\d+)/(\d+)/(\d+)/(\S+)$! or
- die "URI must be \"beh:/<dd>/<att>/<delay>/<original uri>\"!\n";
- my $dontdisable = $1;
- my $attempts = $2;
- my $delay = $3;
- $uri = $4;
- $uri =~ m!^([^:\s]+):!;
- my $backend = $1;
- $ENV{DEVICE_URI} = $uri;
-
- # Control by "lpr" command line options, commented out for security
- # reasons (user could intendedly make queues being disabled)
-
- #$printOptions =~ m/\bBackendErrorDisableQueue=(\S*)\b/ &&
- # ($dontdisable = ($1 =~ /no/i ? 1 : 0));
- #$printOptions =~ m/\bBackendErrorRetries=(\S*)\b/ && ($attempts = $1);
- #$printOptions =~ m/\bBackendErrorRetryDelay=(\S*)\b/ && ($delay = $1);
- #$printOptions =~ m/\bBackendErrorRetryForever=(\S*)\b/ &&
- # ($delay = ($1 =~ /yes/i ? 0 : $delay));
-
- my $exitvalue;
- while($exitvalue = (($uri !~ m!^file:(.*)$!) && ($uri !~ m!^(/.*)$!) ?
- system {"$progpath/$backend"}
- ($uri, $jobID, $userName, $jobTitle, $copies,
- $printOptions, $printFile) :
- system ("cat $printFile > $1")) >> 8) {
- if ($attempts > 0) {
- $attempts --;
- last if $attempts == 0;
- }
- sleep $delay if $delay > 0;
- }
-
- unlink $tempFile if $tempFile;
-
- $exitvalue = 0 if $dontdisable;
- exit $exitvalue;
-